home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / a_utils / perl / msds-prl / prl386ld.zoo / msdos.c < prev    next >
C/C++ Source or Header  |  1992-07-02  |  6KB  |  299 lines

  1. /* $RCSfile: msdos.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:37 $
  2.  *
  3.  *    (C) Copyright 1989, 1990 Diomidis Spinellis.
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  * $Log:    msdos.c,v $
  9.  * Revision 4.0.1.1  91/06/07  11:22:37  lwall
  10.  * patch4: new copyright notice
  11.  * 
  12.  * Revision 4.0  91/03/20  01:34:46  lwall
  13.  * 4.0 baseline.
  14.  * 
  15.  * Revision 3.0.1.1  90/03/27  16:10:41  lwall
  16.  * patch16: MSDOS support
  17.  * 
  18.  * Revision 1.1  90/03/18  20:32:01  dds
  19.  * Initial revision
  20.  *
  21.  */
  22.  
  23. /*
  24.  * Various Unix compatibility functions for MS-DOS.
  25.  */
  26.  
  27. #include "../EXTERN.h"
  28. #include "../perl.h"
  29.  
  30. #include <dos.h>
  31. #ifndef DJGPP
  32. #include <process.h>
  33. #endif /* DJGPP */
  34.  
  35. /*
  36.  * Interface to the MS-DOS ioctl system call.
  37.  * The function is encoded as follows:
  38.  * The lowest nibble of the function code goes to AL
  39.  * The two middle nibbles go to CL
  40.  * The high nibble goes to CH
  41.  *
  42.  * The return code is -1 in the case of an error and if successful
  43.  * for functions AL = 00, 09, 0a the value of the register DX
  44.  * for functions AL = 02 - 08, 0e the value of the register AX
  45.  * for functions AL = 01, 0b - 0f the number 0
  46.  *
  47.  * Notice that this restricts the ioctl subcodes stored in AL to 00-0f
  48.  * In the Ralf Borwn interrupt list 90.1 there are no subcodes above AL=0f
  49.  * so we are ok.
  50.  * Furthermore CH is also restriced in the same area.  Where CH is used as a
  51.  * code it always is between 00-0f.  In the case where it forms a count
  52.  * together with CL we arbitrarily set the highest count limit to 4095.  It
  53.  * sounds reasonable for an ioctl.
  54.  * The other alternative would have been to use the pointer argument to
  55.  * point the the values of CX.  The problem with this approach is that
  56.  * of accessing wild regions when DX is used as a number and not as a
  57.  * pointer.
  58.  */
  59. int
  60. ioctl(int handle, int function, char *data)
  61. {
  62.     union REGS      srv;
  63.     struct SREGS    segregs;
  64.  
  65. #ifdef DJGPP
  66.     fatal("ioctl not supported-H.Doi");
  67.     return(0);
  68. #else
  69.     srv.h.ah = 0x44;
  70.     srv.h.al = (unsigned char)(function & 0x0F);
  71.     srv.x.bx = handle;
  72.     srv.x.cx = function >> 4;
  73.     segread(&segregs);
  74. #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
  75.     segregs.ds = FP_SEG(data);
  76.     srv.x.dx = FP_OFF(data);
  77. #else
  78.     srv.x.dx = (unsigned int) data;
  79. #endif
  80.     intdosx(&srv, &srv, &segregs);
  81. #endif /* DJGPP */
  82.     if (srv.x.cflag & 1) {
  83.         switch(srv.x.ax ){
  84.         case 1:
  85.             errno = EINVAL;
  86.             break;
  87.         case 2:
  88.         case 3:
  89.             errno = ENOENT;
  90.             break;
  91.         case 4:
  92.             errno = EMFILE;
  93.             break;
  94.         case 5:
  95. #ifdef DJGPP
  96.             errno = EACCES;
  97. #else
  98.             errno = EPERM;
  99. #endif /* DJGPP */
  100.             break;
  101.         case 6:
  102.             errno = EBADF;
  103.             break;
  104.         case 8:
  105.             errno = ENOMEM;
  106.             break;
  107.         case 0xc:
  108.         case 0xd:
  109.         case 0xf:
  110.             errno = EINVAL;
  111.             break;
  112.         case 0x11:
  113.             errno = EXDEV;
  114.             break;
  115.         case 0x12:
  116. #ifdef DJGPP
  117.             errno = ENOENT;
  118. #else
  119.             errno = ENFILE;
  120. #endif /* DJGPP */
  121.             break;
  122.         default:
  123. #ifdef DJGPP
  124.             errno = ERANGE;
  125. #else
  126.             errno = EZERO;
  127. #endif /* DJGPP */
  128.             break;
  129.         }
  130.         return -1;
  131.     } else {
  132.         switch (function & 0xf) {
  133.         case 0: case 9: case 0xa:
  134.             return srv.x.dx;
  135.         case 2: case 3: case 4: case 5:
  136.         case 6: case 7: case 8: case 0xe:
  137.             return srv.x.ax;
  138.         case 1: case 0xb: case 0xc: case 0xd:
  139.         case 0xf:
  140.         default:
  141.             return 0;
  142.         }
  143.     }
  144. }
  145.  
  146.  
  147. /*
  148.  * Sleep function.
  149.  */
  150. unsigned int
  151. sleep(unsigned len)
  152. {
  153.     time_t end;
  154.  
  155.     end = time((time_t *)0) + len;
  156.     while (time((time_t *)0) < end)
  157.         ;
  158. }
  159.  
  160. /*
  161.  * Just pretend that everyone is a superuser
  162.  */
  163. #define ROOT_UID    0
  164. #define ROOT_GID    0
  165. unsigned int
  166. getuid(void)
  167. {
  168.     return ROOT_UID;
  169. }
  170.  
  171. unsigned int
  172. geteuid(void)
  173. {
  174.     return ROOT_UID;
  175. }
  176.  
  177. int
  178. getgid(void)
  179. {
  180.     return ROOT_GID;
  181. }
  182.  
  183. int
  184. getegid(void)
  185. {
  186.     return ROOT_GID;
  187. }
  188.  
  189. int
  190. setuid(int uid)
  191. { return (uid==ROOT_UID?0:-1); }
  192.  
  193. int
  194. setgid(int gid)
  195. { return (gid==ROOT_GID?0:-1); }
  196.  
  197. /*
  198.  * The following code is based on the do_exec and do_aexec functions
  199.  * in file doio.c
  200.  */
  201. int
  202. do_aspawn(really,arglast)
  203. STR *really;
  204. int *arglast;
  205. {
  206.     register STR **st = stack->ary_array;
  207.     register int sp = arglast[1];
  208.     register int items = arglast[2] - sp;
  209.     register char **a;
  210.     char **argv;
  211.     char *tmps;
  212.     int status;
  213.  
  214.     if (items) {
  215.     New(1101,argv, items+1, char*);
  216.     a = argv;
  217.     for (st += ++sp; items > 0; items--,st++) {
  218.         if (*st)
  219.         *a++ = str_get(*st);
  220.         else
  221.         *a++ = "";
  222.     }
  223.     *a = Nullch;
  224. #ifdef DJGPP
  225.     {
  226.     char sys_string[256];
  227.     register int i;
  228.  
  229.     if (really && *(tmps = str_get(really)))
  230.         strcpy(sys_string, tmps);
  231.     else
  232.         strcpy(sys_string, argv[0]);
  233.     for (i = 1; argv[i]; i++) {
  234.         strcat(sys_string, " ");
  235.         strcat(sys_string, argv[i]);
  236.     }
  237.     status = system(sys_string);
  238.     }
  239. #else
  240.     if (really && *(tmps = str_get(really)))
  241.         status = spawnvp(P_WAIT,tmps,argv);
  242.     else
  243.         status = spawnvp(P_WAIT,argv[0],argv);
  244. #endif /* DJGPP */
  245.     Safefree(argv);
  246.     }
  247.     return status;
  248. }
  249.  
  250.  
  251. int
  252. do_spawn(cmd)
  253. char *cmd;
  254. {
  255.     register char **a;
  256.     register char *s;
  257.     char **argv;
  258.     char flags[10];
  259.     int status;
  260.     char *shell, *cmd2;
  261.  
  262. #ifdef DJGPP
  263.         return system(cmd);
  264. #else
  265.     /* save an extra exec if possible */
  266.     if ((shell = getenv("COMSPEC")) == 0)
  267.     shell = "\\command.com";
  268.  
  269.     /* see if there are shell metacharacters in it */
  270.     if (strchr(cmd, '>') || strchr(cmd, '<') || strchr(cmd, '|'))
  271.       doshell:
  272.         return spawnl(P_WAIT,shell,shell,"/c",cmd,(char*)0);
  273.  
  274.     New(1102,argv, strlen(cmd) / 2 + 2, char*);
  275.  
  276.     New(1103,cmd2, strlen(cmd) + 1, char);
  277.     strcpy(cmd2, cmd);
  278.     a = argv;
  279.     for (s = cmd2; *s;) {
  280.     while (*s && isspace(*s)) s++;
  281.     if (*s)
  282.         *(a++) = s;
  283.     while (*s && !isspace(*s)) s++;
  284.     if (*s)
  285.         *s++ = '\0';
  286.     }
  287.     *a = Nullch;
  288.     if (argv[0])
  289.     if ((status = spawnvp(P_WAIT,argv[0],argv)) == -1) {
  290.         Safefree(argv);
  291.         Safefree(cmd2);
  292.         goto doshell;
  293.     }
  294.     Safefree(cmd2);
  295.     Safefree(argv);
  296.     return status;
  297. #endif /* DJGPP */
  298. }
  299.